/**
 * 
 */
package com.zznode.redsun.commons.sercurity.shiro;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.zznode.redsun.commons.sercurity.mapper.SecurityMapper;
import com.zznode.redsun.commons.sercurity.model.Account;
import com.zznode.redsun.commons.sercurity.model.Permission;
import com.zznode.redsun.commons.sercurity.model.Role;

/**
 * @author taoping
 * 
 */
public class JdbcShiroRealm extends AuthorizingRealm {
	private static final Logger logger = LoggerFactory.getLogger(JdbcShiroRealm.class);

	@Autowired
	private SecurityMapper securityMapper;

	// 获取授权信息
	@Override
	public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		logger.info("Get name value : " + getName());
		// String loginName = (String) principals.fromRealm(getName()).iterator().next();
		String loginName = principals.getPrimaryPrincipal().toString();
		Object realms = principals.getRealmNames();
		logger.info("===>>Realm : " + realms);
		SimpleAuthorizationInfo simpleInfo = new SimpleAuthorizationInfo();
		if (null != loginName) {
			Collection<Role> roles = securityMapper.findRoles(loginName);
			for (Role entry : roles) {
				simpleInfo.addRole(entry.getCode());
			}
			Collection<Permission> permissions = securityMapper.findPermissions(loginName);
			for (Permission entry : permissions) {
				simpleInfo.addStringPermission(entry.getCode());
			}
		}

		return simpleInfo;
	}

	// 获取认证信息
	@Override
	public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authentToken) throws AuthenticationException {
		UsernamePasswordToken userToken = (UsernamePasswordToken) authentToken;
		String loginName = userToken.getUsername();
		if (StringUtils.hasText(loginName)) {
			Account account = null;
			try {
				account = securityMapper.getAccount(loginName);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new AuthenticationException(e);
			}
			if (null == account) {
				throw new UnknownAccountException("帐号不存在:" + loginName);
			}
			if (null != account.getEnabled() && account.getEnabled().booleanValue()) {
				// SimpleAuthenticationInfo simpleInfo = new SimpleAuthenticationInfo(account.getCode(),
				// account.getPassword(), account.getName());
				Set<String> roles = new HashSet<String>();
				Collection<Role> roleReslut = securityMapper.findRoles(loginName);
				for (Role entry : roleReslut) {
					roles.add(entry.getCode());
				}

				Set<org.apache.shiro.authz.Permission> permissions = new HashSet<org.apache.shiro.authz.Permission>();
				Collection<Permission> queryResult = securityMapper.findPermissions(loginName);
				for (Permission entry : queryResult) {
					permissions.add(new WildcardPermission(entry.getCode()));
				}

				AuthenticationInfo authentication = null;
				try {
					LoginUser<Long> loginUser = new LoginUserBuilder(account).build();
					authentication = new SimpleAccount(loginUser, account.getPassword(), "Smart-CRM", roles,
							permissions);
				} catch (Throwable ex) {
					logger.error(ex.getMessage(), ex);
					throw new AuthenticationException(ex);
				}
				return authentication;
			} else {
				throw new LockedAccountException("帐号未激活，请与管理员联系");
			}
		}
		return null;
	}
}
